package com.pay.ioopos.fragment;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;

import com.pay.ioopos.BindState;
import com.pay.ioopos.IconFontFactory;
import com.pay.ioopos.R;
import com.pay.ioopos.SubScreenBackgroudLoader;
import com.pay.ioopos.SubScreenFactory;
import com.pay.ioopos.receiver.ReportReceiver;

import static com.pay.ioopos.fragment.TipFragment.TipType.ERROR;
import static com.pay.ioopos.fragment.TipFragment.TipType.EXPIRED;
import static com.pay.ioopos.fragment.TipFragment.TipType.FAIL;
import static com.pay.ioopos.fragment.TipFragment.TipType.SUCCESS;
import static com.pay.ioopos.fragment.TipFragment.TipType.WAIT;

public abstract class PayIngAbstract extends TipHorizontalFragment implements BindState {
    private PayFinishListener listener;
    protected String barcode;
    protected String amount;
    private boolean isWeixinPay;

    public PayIngAbstract(PayFinishListener listener, String barcode, String amount) {
        super(WAIT, "正在支付");
        this.listener = listener;
        this.barcode = barcode;
        this.amount = amount;
        this.isWeixinPay = isWeixinPay();

    }

    @Override
    public boolean useNetwork() {
        return true;
    }

    @Override
    protected void execute() throws Exception {
        SubScreenFactory.startSubScreen(this::flushSubScreenToPaying);
    }

    @Override
    public void onError(String msg) {
        showToast(msg);
        showPayError();
    }

    protected void showPayPwd() {
        onChange(WAIT, R.string.pay_pwd);
        speak(R.string.please_type_in_pwd);
        SubScreenFactory.startSubScreen(this::flushSubScreenToPayPwd);
    }

    protected void showPaySuccess(String orderNo, String channelOrderNo) {
        showPaySuccess();
        if (isWeixinPay) {
            reportData(orderNo, channelOrderNo);
        }
    }

    protected void showPaySuccess() {
        onChange(SUCCESS, R.string.pay_success);
        speak(R.string.pay_success);
        SubScreenFactory.startSubScreen(this::flushSubScreenToPaySuccess);
        listener.onFinish();
    }

    protected void showPayFail(String msg) {
        showToast(msg);
        onChange(FAIL, R.string.pay_fail);
        speak(R.string.pay_fail);
        SubScreenFactory.startSubScreen(this::flushSubScreenToPayFail);
        listener.onFinish();
    }

    protected void showPayExpired() {
        onChange(EXPIRED, R.string.pay_expired);
        speak(R.string.pay_expired);
        SubScreenFactory.startSubScreen(this::flushSubScreenToPayExpired);
        listener.onFinish();
    }

    protected void showPayError() {
        onChange(ERROR, R.string.pay_error);
        speak(R.string.pay_error);
        SubScreenFactory.startSubScreen(this::flushSubScreenToPayError);
        listener.onFinish();
    }

    protected boolean isWeixinPay() {
        if (barcode.length() != 18) {
            return false;
        }
        int pre = Integer.parseInt(barcode.substring(0, 2));
        return pre >= 10 && pre <=15;
    }

    protected boolean isAlipayPay() {
        int length = barcode.length();
        if (length >= 16 && length <=24) {
            int pre = Integer.parseInt(barcode.substring(0, 2));
            return pre >= 25 && pre <=30;
        }
        return false;
    }

    protected boolean isUnionPay() {
        int length = barcode.length();
        if (length == 19) {
            int pre = Integer.parseInt(barcode.substring(0, 2));
            return pre == 62;
        }
        return false;
    }

    private void reportData(String outTradeNo, String transactionId) {
        Intent intent = new Intent(ReportReceiver.class.getName());
        intent.putExtra("out_trade_no", outTradeNo);
        intent.putExtra("transaction_id", transactionId);
        getContext().sendBroadcast(intent);
    }

    private void flushSubScreenToPaySuccess() {
        flushSubScreenToPayStatus(SubScreenBackgroudLoader.getInstance().getPaySuccessBitmap(),R.color.colorSuccess, R.string.glyphicon_ok_sign, R.string.pay_success);
    }

    private void flushSubScreenToPaying() {
        flushSubScreenToPayStatus(SubScreenBackgroudLoader.getInstance().getPayingBitmap(), R.color.colorWarning, R.string.glyphicon_exclamation_sign, R.string.pay_paying);
    }

    private void flushSubScreenToPayPwd() {
        flushSubScreenToPayStatus(SubScreenBackgroudLoader.getInstance().getPayingBitmap(), R.color.colorWarning, R.string.glyphicon_exclamation_sign, R.string.please_type_in_pwd);
    }

    private void flushSubScreenToPayFail() {
        flushSubScreenToPayStatus(SubScreenBackgroudLoader.getInstance().getPayFailBitmap(), R.color.colorDanger, R.string.glyphicon_remove_sign, R.string.pay_fail);
    }

    private void flushSubScreenToPayExpired() {
        flushSubScreenToPayStatus(SubScreenBackgroudLoader.getInstance().getPayFailBitmap(), R.color.colorDanger, R.string.glyphicon_remove_sign, R.string.pay_expired);
    }

    private void flushSubScreenToPayError() {
        flushSubScreenToPayStatus(SubScreenBackgroudLoader.getInstance().getPayUnknownBitmap(), R.color.colorDanger, R.string.glyphicon_remove_sign, R.string.pay_error);
    }

    private void flushSubScreenToPayStatus(Bitmap bitmap, int colorId, int iconId, int textId) {
        Context context = getContext();
        if (null == context) {
            return;
        }

        Bitmap dstBitmap;
        Canvas canvas;
        if (null == bitmap) {
            dstBitmap = SubScreenFactory.createBitmap();
            canvas = new Canvas(dstBitmap);
            canvas.drawColor(Color.WHITE);
        } else {
            dstBitmap = SubScreenFactory.scaledBitmap(bitmap);
            canvas = new Canvas(dstBitmap);
        }

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextSize(80f);

        int moneyWidth = (int) paint.measureText(amount);
        int startX = (dstBitmap.getWidth() - moneyWidth) / 2;
        canvas.drawText(amount, startX, 170, paint);

        Paint iconPaint = new Paint();
        iconPaint.setAntiAlias(true);
        iconPaint.setTextSize(40f);
        iconPaint.setColor(context.getColor(colorId));
        Typeface typeface = IconFontFactory.getHalflings(context);
        iconPaint.setTypeface(typeface);

        String icon = getString(iconId);
        int iconWidth = (int) iconPaint.measureText(icon);

        Paint textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(30f);

        String text = getString(textId);
        int textWidth = (int) textPaint.measureText(text);

        startX = (dstBitmap.getWidth() - iconWidth - textWidth) / 2;
        canvas.drawText(icon, startX, 230, iconPaint);

        startX = startX + iconWidth + 10;
        canvas.drawText(text, startX, 220, textPaint);

        canvas.save();
        canvas.restore();

        SubScreenFactory.flush(dstBitmap);

    }

    public String getAmount() {
        return amount;
    }

    public interface PayFinishListener {
        void onFinish();
    }
}
